SNS トピックには同じエンドポイントを持つ SNS サブスクリプションを複数関連づけられない
コンバンハ、千葉(幸)です。
SNS トピックには複数の SNS サブスクリプションを関連づけられます。
SNS サブスクリプションはプロトコル、エンドポイントといったパラメータを持ちます。例えば SNS トピックを通じた Eメール配信を行いたければ、プロトコルに「Eメール」、エンドポイントに送信先メールアドレスを設定します。
ここで、同じ SNS トピックに同じエンドポイントを持つ SNS サブスクリプションを複数関連づけたいことがありました。
結果から言うとこの構成は実現できませんでした。試した内容をまとめておきます。
なぜ同じエンドポイントを持つ SNS サブスクリプションを複数設定したいのか
先に、なぜやりたかったのかを説明しておきます。「SNS サブスクリプションの空白期間を設けずConfirmationWasAuthenticated
属性を変更したかったから」です。
SNS サブスクリプションにはConfirmationWasAuthenticated
という属性があり、true / false のいずれかを持ちます。これは SNS サブスクリプションの確認(初回登録)が認証有りで行われたかどうかを表す属性であり、これが false の場合、IAM 認証なしでサブスクリプション解除できてしまう状態です。
以下エントリのように「いつの間にかサブスクリプションが削除されていた」という事態になりかねません。
既存の SNS サブスクリプションのConfirmationWasAuthenticated
属性が false であったため、これを true に切り替えたいと考えました。
SNS サブスクリプション属性の変更はできないため、既存のサブスクリプションの削除→新規サブスクリプションの作成というステップを踏む必要があります。
ここで、サブスクリプションが存在しない期間をなるべく設けたくなく、以下のプロセスで実現できないか考えました。
- 新規の SNS サブスクリプション(true)を追加する
- 既存の SNS サブスクリプション(false)を削除する
このプロセスを踏む場合、同じエンドポイントを持つサブスクリプションが一時的に同居することになります。が、冒頭で述べた通り、これは実現できません。
SNS トピックに重複するエンドポイントを持つ SNS サブスクリプションを追加してみる
同じエンドポイントを複数設定できるのか?について AWS ドキュメント上ではそれらしき記述が確認できなかったので、実際に手を動かして確認してみます。
作業前の状態は以下です。
SNS トピックtest-topic
に、ひとつのサブスクリプションが関連づいています。プロトコルは Eメールで、エンドポイントは[email protected]
です。(実際のアドレスではなく例示用のものです。)
サブスクリプションに払い出された ID はfa87649c-2fe6-47e0-937a-a4e4830330b3
です。
この状態からさらにサブスクリプションを追加してみます。画像内の「サブスクリプションの作成」を押下し作成画面に遷移し、以下のように設定します。
正常に作成が完了したように表示されました。
しかし、払い出された ID を確認すると既存のものと同じfa87649c-2fe6-47e0-937a-a4e4830330b3
です。ステータスもすでに「確認済み」となっています。
SNS トピックの画面に戻って確認しても、新規の SNS サブスクリプションは確認できません。
ちなみに、Confirm 用のメールは改めて送信されています。特にこれは意味を持ちません。メール内の Confirm 用のリンクを押下しても特にステータスは変わりません。
AWS CLI でも確認してみる
マネジメントコンソール上での操作だけでなく、AWS CLI でも確認してみます。aws sns subscribe
コマンドを使用します。
# 変数の格納 TOPIC_ARN=arn:aws:sns:ap-northeast-1:000000000000:test-topic [email protected] # コマンドの実行 % aws sns subscribe \ --topic-arn $TOPIC_ARN \ --protocol email \ --notification-endpoint $ENDPOINT { "SubscriptionArn": "pending confirmation" }
pending confirmation
という出力が返ってきましたが、「保留中の確認」ステータスのサブスクリプションが作成されたわけではありません。
マネジメントコンソールと同じ以下の状態です。
- Confirm 用のメールは届く
- メール内の Confirm 用リンクを押下した際に確認できるサブスクリプション ID は
fa87649c-2fe6-47e0-937a-a4e4830330b3
(既存のものと同じ) - 新規のサブスクリプションは確認できない
操作の手法によらず、同じエンドポイントを持つ SNS サブスクリプションを単一トピックに同居させられないことがわかりました。
ConfirmationWasAuthenticated 属性を切り替えたい際にどうしたらいいのか
冒頭で述べた「SNS サブスクリプションの空白期間を設けずConfirmationWasAuthenticated
属性を変更」は実現できないことが分かりました。
代替策としては以下のあたりがあるでしょう。
- 既存 SNS サブスクリプションの削除→新規 SNS サブスクリプションの作成をなるべく間を置かずに実施する
- 別のエンドポイントの SNS サブスクリプションを一時的に追加し、「削除→新規」の作業中の通知をそちらで受ける
- Webメールによってはエイリアス機能を持つものがあるのでそちらの活用もあり
新規の SNS トピックを作成してそちらに切り替える、という手法もありますが、手間が大きい気もします。許容できる空白期間と作業ボリュームを鑑みて、よき案を採用してください。
終わりに
SNS トピックに同じエンドポイントを持つ SNS サブスクリプションを複数関連づけられない、という話でした。
試してみた挙動からすると、SNS トピックとプロトコル・エンドポイントの組み合わせごとに一意の ID が払い出され、複数回「作成」や「Subscribe」を実行しても別物として扱われない、ということだと捉えました。
今回のような背景がない限り「複数持ちたい」というケースはあまり無いと思いますが、参考になれば幸いです。
以上、 チバユキ (@batchicchi) がお送りしました。